package xyz.yuzegod.megawalls.classes.mythic.phoenix;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector;
import xyz.yuzegod.megawalls.MegaWalls;
import xyz.yuzegod.megawalls.classes.Classes;
import xyz.yuzegod.megawalls.classes.Skill;
import xyz.yuzegod.megawalls.game.GamePlayer;
import xyz.yuzegod.megawalls.stats.KitStatsContainer;
import xyz.yuzegod.megawalls.util.ParticleEffect;
import xyz.yuzegod.megawalls.util.PlayerUtils;
import xyz.yuzegod.megawalls.util.StringUtils;

import java.util.*;

public class SecondSkill extends Skill
{
    private static final Set<Material> set;
    
    public SecondSkill(final Classes classes) {
        super("灵魂契约", classes);
    }
    
    @Override
    public int maxedLevel() {
        return 3;
    }
    
    @Override
    public double getAttribute(final int level) {
        switch (level) {
            case 1: {
                return 0.05;
            }
            case 2: {
                return 0.1;
            }
            case 3: {
                return 0.15;
            }
            default: {
                return 0.05;
            }
        }
    }
    
    @Override
    public List<String> getInfo(final int level) {
        final List<String> lore = new ArrayList<String>();
        if (level == 1) {
            lore.add(" §8▪ §7用剑右键点击一名队友与之订立契约");
            lore.add(" §8▪ §7契约将在你和契约对象相距16格范围内时生效");
            lore.add(" §8▪ §7契约生效时,每3.75秒你和队友均恢复1点生命值");
            lore.add(" §8▪ §7战墙倒塌后,你的队友同时每秒恢复其每次攻击获得能量最高值的§a" + StringUtils.percent(this.getAttribute(level)));
            lore.add(" §8▪ §7其他来源的生命恢复效果将会暂停契约生命恢复");
            return lore;
        }
        lore.add(" §8▪ §7战墙倒塌后,你的队友同时每秒恢复其每次攻击获得能量最高值的§8" + StringUtils.percent(this.getAttribute(level - 1)) + " ➜");
        lore.add("   §a" + StringUtils.percent(this.getAttribute(level)));
        return lore;
    }
    
    @Override
    public void upgrade(final GamePlayer gamePlayer) {
        final KitStatsContainer kitStats = gamePlayer.getPlayerStats().getKitStats(this.getClasses());
        kitStats.addSkill2Level();
    }
    
    @Override
    public int getPlayerLevel(final GamePlayer gamePlayer) {
        return gamePlayer.getPlayerStats().getKitStats(this.getClasses()).getSkill2Level();
    }
    
    @Override
    public String getSkillTip(final GamePlayer gamePlayer) {
        String player = "§7§l无";
        final GamePlayer target = Phoenix.target.getOrDefault(gamePlayer, null);
        if (target != null) {
            final double distance = target.getPlayer().getLocation().distance(gamePlayer.getPlayer().getLocation());
            player = ((distance >= 5.0) ? "§e§l" : "§a§l") + target.getPlayer().getDisplayName();
        }
        return this.getClasses().getNameColor() + this.getName() + " " + player + ((Phoenix.skill2Cooldown.getOrDefault(gamePlayer, 0) > 0) ? ("§7(" + Phoenix.skill2Cooldown.getOrDefault(gamePlayer, 0) + ")") : "");
    }
    
    @Override
    public boolean use(final GamePlayer gamePlayer, final KitStatsContainer kitStats) {
        return true;
    }
    
    public static boolean useSkill(final GamePlayer gamePlayer, final GamePlayer targetPlayer) {
        if (Phoenix.target.getOrDefault(gamePlayer, null) != null) {
            gamePlayer.sendMessage("§c请等待冷却完毕！");
            return false;
        }
        final Player player = gamePlayer.getPlayer();
        Player target = null;
        for (final Block block : player.getLineOfSight(SecondSkill.set, 16)) {
            for (final Player player2 : getNearbyPlayers(block.getLocation(), player, 2)) {
                if (target == null || player2.getLocation().distance(player.getLocation()) < target.getLocation().distance(player.getLocation())) {
                    target = player2;
                }
            }
        }
        if (target == null) {
            player.sendMessage("§c没有玩家在目标范围内！");
            return false;
        }
        Phoenix.target.put(gamePlayer, targetPlayer);
        gamePlayer.sendMessage("§a§l与" + targetPlayer.getPlayer().getDisplayName() + "订立契约！");
        targetPlayer.sendMessage("§a§l你收到了" + gamePlayer.getPlayer().getDisplayName() + "的契约！");
        Phoenix.skill2Cooldown.put(gamePlayer, 40);
        new BukkitRunnable() {
            private int i = 0;
            
            public void run() {
                final GamePlayer tagetPlayer = Phoenix.target.getOrDefault(gamePlayer, null);
                if (tagetPlayer == null || !gamePlayer.isOnline() || !tagetPlayer.isOnline() || tagetPlayer.getPlayer().getLocation().distance(gamePlayer.getPlayer().getLocation()) > 16.0) {
                    Phoenix.target.put(gamePlayer, null);
                    if (tagetPlayer != null) {
                        gamePlayer.sendMessage("§a§l你与" + targetPlayer.getPlayer().getDisplayName() + "的契约已失效！");
                        targetPlayer.sendMessage("§a§l" + gamePlayer.getPlayer().getDisplayName() + "与你的契约已失效！");
                    }
                    this.cancel();
                    return;
                }
                if (this.i % 2 == 0) {
                    final Location loc = player.getLocation().clone();
                    final Location tagetLoc = tagetPlayer.getPlayer().getLocation();
                    final Iterator<Block> itr = (Iterator<Block>)new BlockIterator(loc.getWorld(), loc.toVector(), new Vector(tagetLoc.getX() - loc.getX(), tagetLoc.getY() - loc.getY(), tagetLoc.getZ() - loc.getZ()), player.getEyeHeight(), 10);
                    while (itr.hasNext()) {
                        final Block block = itr.next();
                        ParticleEffect.HEART.display(0.0f, 0.0f, 0.0f, 0.0f, 1, block.getLocation().clone(), 10.0);
                    }
                    PlayerUtils.heal(gamePlayer.getPlayer(), 1.0);
                    PlayerUtils.heal(tagetPlayer.getPlayer(), 1.0);
                }
                ++this.i;
            }
        }.runTaskTimer((Plugin)MegaWalls.getInstance(), 0L, 20L);
        return true;
    }
    
    private static List<Player> getNearbyPlayers(final Location location, final Player player, final int radius) {
        final List<Player> players = new ArrayList<Player>();
        final GamePlayer gamePlayer = GamePlayer.get(player.getUniqueId());
        for (final Player other : PlayerUtils.getNearbyPlayers(location, radius)) {
            final GamePlayer gameOther = GamePlayer.get(other.getUniqueId());
            if (!gamePlayer.equals(gameOther) && !gameOther.isSpectator() && gamePlayer.getGameTeam().isInTeam(gameOther)) {
                if (other.getLocation().distance(location) > radius) {
                    continue;
                }
                players.add(other);
            }
        }
        return players;
    }
    
    static {
        set = new HashSet<Material>();
        for (final Material material : Material.values()) {
            SecondSkill.set.add(material);
        }
    }
}
